<template>
  <view class="benben-slide-box">
    <view
      class="benben-slide"
      :style="{
        'z-index': left != 0 ? 19 : 1,
      }"
    >
      <view class="benben-slide-center" :style="centerStyle" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend">
        <slot></slot>
      </view>
      <view class="benben-slide-additional" :style="additionalStyle">
        <slot name="additional"></slot>
      </view>
    </view>
    <view @click="reset" @touchstart="reset" @touchmove="reset" @touchend="reset" v-if="auto && left != 0" class="slide-mask"></view>
  </view>
</template>
<script>
export default {
  name: 'benben-swipe-action',
  props: {
    //是否禁用
    disable: {
      type: Boolean,
      default: false,
    },
    auto: {
      type: Boolean,
      default: false,
    },
    //滑动状态
    value: {
      type: [Boolean, String, Number],
      default: false,
    },
    slideType: {
      type: String,
      default: 'right',
    },
  },
  computed: {
    additionalStyle() {
      return `height: ${this.height}px;${this.slideType}: 0`
    },
    centerStyle() {
      return `left: ${this.left}px`
    },
  },
  data() {
    return {
      x: 0,
      left: 0,
      moveState: false,
      operation: 0,
      height: 0,
    }
  },
  watch: {
    value(val) {
      if (val === this.moveState) return
      if (val) {
        this.left = this.operation
      } else {
        this.left = 0
      }
      this.moveState = val
    },
  },
  mounted() {
    this.moveState = this.value
    this.$nextTick((res) => {
      this.getBtnWidth(this.moveState)
      this.getListHeight()
    })
  },
  methods: {
    //重置方法
    reset() {
      this.left = 0
      this.changeMoveState(false)
    },
    changeMoveState(e) {
      if (e === this.moveState) return
      this.moveState = e
      this.$emit('input', e)
      this.$emit('change', e)
    },
    getBtnWidth(type) {
      let view = uni.createSelectorQuery().in(this).select('.benben-slide-additional')
      view
        .boundingClientRect((rect) => {
          this.operation = this.slideType == 'right' ? -rect.width : rect.width
          if (type) this.left = this.operation
        })
        .exec()
    },
    getListHeight() {
      let view = uni.createSelectorQuery().in(this).select('.benben-slide-center')
      view
        .boundingClientRect((rect) => {
          this.height = rect.height
        })
        .exec()
    },
    touchstart(e) {
      if (this.disable) return
      this.x = e.touches[0].clientX
    },
    touchmove(e) {
      if (this.disable) return
      let move = e.touches[0].clientX - this.x
      this.x = e.touches[0].clientX
      let left = this.left + move
      if (this.slideType == 'right') {
        if (left > 0) left = 0
        if (left < this.operation) {
          left = this.operation
        }
      } else {
        if (left < 0) left = 0
        if (left > this.operation) {
          left = this.operation
        }
      }
      this.left = left
    },
    touchend(e) {
      if (this.disable) return
      let left = this.left
      if (
        (this.slideType == 'right' && (left > 0 || left > this.operation / 2)) ||
        (this.slideType == 'left' && (left < 0 || left < this.operation / 2))
      ) {
        this.changeMoveState(false)
        left = 0
      } else {
        this.changeMoveState(true)
        left = this.operation
      }
      this.left = left
    },
  },
}
</script>

<style scoped>
.benben-slide-box {
  position: relative;
  width: 100%;
  border-radius: inherit;
}

.slide-mask {
  position: fixed;
  left: 0;
  top: 0;
  width: 100vw;
  height: 100vh;
  /* background-color: pink; */
  z-index: 18;
}

.benben-slide {
  position: relative;
  overflow: hidden;
  border-radius: inherit;
}

.benben-slide-center {
  position: relative;
  left: 0;
  width: 100%;
  overflow: hidden;
  transition: left 0.2s ease-in-out;
  z-index: 1;
}

.benben-slide-additional {
  position: absolute;
  top: 0;
  display: flex;
  align-items: center;
}
</style>
